//
//  SEGIAnalyticsDBManager.m
//  test
//
//  Created by 刘山 on 2017/12/3.
//  Copyright © 2017年 刘山. All rights reserved.
//

#import "SEGIAnalyticsDBManager.h"
#import <objc/runtime.h>
#import <FMDB.h>

static FMDatabaseQueue* _queue;
static FMDatabase* _database;


@implementation SEGIAnalyticsDBManager

/**
 * 创建数据库
 * @author Sam
 * @param dbName  数据库名
 */
+(void)segCreateDBWithDbName:(NSString*)dbName{
    _queue = [FMDatabaseQueue databaseQueueWithPath:[self filePath:dbName]];
}

/**
 * 创建数据表
 * @author Sam
 * @param aName  数据库名
 * @param table  创建表的SQL语句
 * demo: create table bulktest1 (id integer primary key autoincrement, x text);
 */
+ (BOOL)segCreateTableWithDBName:(NSString*)aName WithTable:(NSString*)table
{
    __block BOOL _isCreateTable = NO;
    
    [self segCreateDBWithDbName:aName];
    
    // 3.创表
    [_queue inDatabase:^(FMDatabase* db) { // 这句代码内部包含了创建数据库实例
        
        if (db.open) {
            _isCreateTable = [db executeUpdate:table];
        }
        [db close];
        
    }];
    
    [_queue close];
    
    return _isCreateTable;
}

/**
 * 插入数据
 * @author Sam
 * @param data   数据字典
 * @param aName  数据库名
 * @param table  创建表的SQL语句
 */
+ (BOOL)segInsertWithDictionary:(NSDictionary*)data DBName:(NSString*)aName WithTable:(NSString*)table{
    __block BOOL _isInsert = NO;
    
    [self segCreateDBWithDbName:aName];
    
    if (!_queue) {
        return _isInsert;
    };
    
    __block NSMutableString* value_table = [NSMutableString string];
    __block NSMutableString* value = [NSMutableString string];
    NSArray *allKeys = [data allKeys];
    
    [allKeys enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString *content = (idx == allKeys.count - 1) ? [NSString stringWithFormat:@"%@", obj] : [NSString stringWithFormat:@"%@,", obj];
        [value_table appendString:content];
        
        content = (idx == allKeys.count - 1) ? [NSString stringWithFormat:@":%@", obj] : [NSString stringWithFormat:@":%@,", obj];
        [value appendString:content];
        
    }];
    
    NSString *sql = [NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES(%@)", table,value_table,value];
    
    [_queue inDatabase:^(FMDatabase* db) {
        _isInsert = [db executeUpdate:sql withParameterDictionary:data];
    }];
    
    [_queue close];
    
    return _isInsert;
}

/**
 *  查询数据
 *  @author Sam
 *  @param aName  数据库名
 *  @param sql    查询语句
 *  @param values 查询参数
 *  @return 返回值：Array
 *  示例：NSArray* arr = [SEGBasicDataBase executeQueryWithDBName:DBName WithSQL:@"SELECT * FROM t_table WHERE sex = ?" OfValues:@[ @0 ]];
 */
+ (NSArray*)segExecuteQueryWithDBName:(NSString*)aName WithSQL:(NSString*)sql OfValues:(NSArray*)values
{
    NSArray* _result = [NSArray array];
    
    [self segCreateDBWithDbName:aName];
    
    if (!_queue) {
        return nil;
    }
    
    __block FMResultSet* _rs;
    
    __block NSMutableArray* _arrM = [NSMutableArray array];
    
    if (values.count == 0) {
        
        [_queue inDatabase:^(FMDatabase* db) {
            
            _rs = [db executeQuery:sql];
            
            while ([_rs next]) {
                
                NSDictionary* _dic = _rs.resultDictionary;
                
                [_arrM addObject:_dic];
            }
            
            [_rs close];
            
        }];
    }
    else {
        
        [_queue inDatabase:^(FMDatabase* db) {
            
            _rs = [db executeQuery:sql withArgumentsInArray:values];
            
            while ([_rs next]) {
                
                NSDictionary* _dic = _rs.resultDictionary;
                
                [_arrM addObject:_dic];
            }
            
            [_rs close];
            
        }];
    }
    
    [_queue close];
    
    _result = _arrM;
    
    return _result;
}

/**
 *  插入、修改、删除 数据表
 *  @author Sam
 *  @param aName  数据库名
 *  @param sql    执行的SQL语句(条件的数值用：？来隔离)
 *  @param values 条件数值
 *  示例：[SEGIAnalyticsDBManager segExecuteDB:DBName WithSQL:@"delete from t_table where age > ?;" OFValues:@[ @(2) ]];
 */
+ (BOOL)segExecuteDB:(NSString*)aName WithSQL:(NSString*)sql OfValues:(NSArray*)values{
    __block BOOL _isExecute = NO;
    
    [self segCreateDBWithDbName:aName];
    
    [_queue inDatabase:^(FMDatabase* db) {
        
        if (db.open) {
            _isExecute = [db executeUpdate:sql withArgumentsInArray:values];
        }
        [db close];
    }];
    
    [_queue close];
    
    return _isExecute;
}

+ (NSString*)filePath:(NSString*)name
{
    return [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite", name]];
}


/**
 * 获取模型中所有字段的名字
 * @author Sam
 * @param mdoel  模型名
 */
+(NSArray*)segAllKeysFromModel:(id)mdoel{
    if (!mdoel) return nil;
    
    NSMutableArray *allKeys = [NSMutableArray array];
    unsigned int count = 0;
    objc_property_t *propertes = class_copyPropertyList(mdoel, &count);
    for (int i=0; i<count; i++) {
        const char *propertyName = property_getName(propertes[i]);
        NSString *name = [NSString stringWithUTF8String:propertyName];
        [allKeys addObject:name];
    }
    return [NSArray arrayWithArray:allKeys];
}

+ (BOOL) isTableOK:(NSString *)tableName DB:(NSString*)aName
{
    NSString *name =nil;
    BOOL isExistTable = NO;
    FMDatabase * db = [FMDatabase databaseWithPath:[self filePath:aName]];
    if ([db open]) {
        NSString * sql = [[NSString alloc]initWithFormat:@"select name from sqlite_master where type = 'table' and name = '%@'",tableName];
        FMResultSet * rs = [db executeQuery:sql];
        while ([rs next]) {
            name = [rs stringForColumn:@"name"];
            
            if ([name isEqualToString:tableName])
            {
                isExistTable = YES;
            }
        }
        [db close];
    }
    return isExistTable;
}
@end
